package redis

import (
	"github.com/go-redis/redis/v7"
	"github.com/go-redsync/redsync/v4"
	"github.com/go-redsync/redsync/v4/redis/goredis/v7"
	"log"
	"time"
	"ttsApp/internal/config"
)

var Client *redis.Client
var SyncClient *redsync.Redsync

func InitRedis() (*redis.Client, *redsync.Redsync) {
	model := config.C.Redis.Model
	var client *redis.Client
	log.Printf("redisConfig:%v", config.C.Redis)
	if model == "sentinel" {
		client = redis.NewFailoverClient(&redis.FailoverOptions{
			MasterName:    config.C.Redis.Sentinel.MasterName,
			SentinelAddrs: config.C.Redis.Sentinel.SentinelAddress,
			Password:      config.C.Redis.Sentinel.Password,
			DB:            config.C.Redis.Sentinel.DB,
		})
	} else {
		client = redis.NewClient(&redis.Options{
			Addr:     config.C.Redis.Addr,
			Password: config.C.Redis.Password,
			DB:       config.C.Redis.DB,
		})
	}

	if _, err := client.Ping().Result(); err != nil {
		log.Fatalf("Failed to connect to Redis: %v", err)
	}
	pool := goredis.NewPool(client)
	redisSyncCli := redsync.New(pool)
	return client, redisSyncCli
}
func setKeyExpire(key string) error {
	// 设置键的过期时间为三天（以秒为单位）
	expireDuration := time.Duration(72) * time.Hour // 3 days in seconds
	return Client.Expire(key, expireDuration).Err()
}
func LPush(key string, value string) error {
	_, e := Client.LPush(key, value).Result()
	if e != nil {
		return e
	}
	return setKeyExpire(key)
}

func RPop(key string) (string, error) {
	e := setKeyExpire(key)
	if e != nil {
		return "", e
	}
	return Client.RPop(key).Result()
}

func Publish(channel string, message string) (int64, error) {
	return Client.Publish(channel, message).Result()
}

func ExecRedisSyncJob(
	lockKey string,
	job func() error,
) error {
	redisLock := SyncClient.NewMutex(lockKey)
	err := redisLock.Lock()
	if err != nil {
		log.Printf("Failed to acquire lock: %v", err)
		return err
	}
	defer func(redisLock *redsync.Mutex) {
		ok, err := redisLock.Unlock()
		if ok {
			//log.Printf("成功释放分布式锁")
		}
		if err != nil || !ok {
			log.Printf("释放分布式锁失败，现在强制删除锁")
			Client.Del(lockKey)
		}
	}(redisLock)
	//log.Printf("成功获得分布式锁")
	err = job()
	//log.Printf("任务执行完成!")
	return err
}
